package com.hong.spring.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;
import com.hong.spring.entity.User;
import com.hong.spring.service.IUserService;
import com.hong.spring.utils.DataResponse;
import lombok.SneakyThrows;
import lombok.extern.log4j.Log4j2;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import static java.util.concurrent.Executors.*;

/**
 * @Auther: csh
 * @Date: 2020/8/18 16:11
 * @Description:
 */
@RestController
@RequestMapping("/user/")
@Log4j2
public class UserController{
    @Autowired
    private IUserService userService;

    // 创建布隆过滤器对象
    BloomFilter filter = BloomFilter.create(
            Funnels.integerFunnel(),
            1500,
            0.01);
    {
        for(int i=0;i<44;i++){
            filter.put(i);
        }
    }

    @RequestMapping("findByAll")
    public DataResponse<List<User>> findByAll(){
        try {
            return userService.findByAll();
        } catch (Exception e){
            log.error("查询出错{}",e);
        }
        return DataResponse.BuildFailResponse("查询出错!");
    }
    /**
     *
     * 功能描述:通过id查询
     *
     * @param:
     * @return:
     * @auther: csh
     * @date: 2020/8/31 17:29
     */
    @RequestMapping("findById/{id}")
    public DataResponse<User> findById(@PathVariable("id")Integer id){
        if(null==id){
            return DataResponse.BuildFailResponse("参数不能为空!");
        }
        try {
            //定义一个拥有20个并发的线程池对象
            ExecutorService service = newFixedThreadPool(20);
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    userService.findById(id);
                }
            };
            for (int i = 0; i < 10000; i++) {
                //提交线程，并并发执行
                service.submit(runnable);
            }
            return userService.findById(id);
        }catch (Exception e){
            log.error("findById->查询失败{}",e);
            return DataResponse.BuildFailResponse("查询出错请重试!");
        }
    }



    /**
     *
     * 功能描述:通过id查询
     *
     * @param:
     * @return:
     * @auther: csh
     * @date: 2020/8/31 17:29
     */
    @RequestMapping("findById2/{id}")
    public DataResponse<User> findById2(@PathVariable("id")Integer id){
        if(null==id){
            return DataResponse.BuildFailResponse("参数不能为空!");
        }
        try {
            // 判断指定元素是否存在
            log.info("是否包含该id："+filter.mightContain(id));
            // 将元素添加进布隆过滤器
            if(!filter.mightContain(id)){
                return DataResponse.BuildFailResponse("该数据不存在");
            }
            return userService.findById(id);
        }catch (Exception e){
            log.error("findById->查询失败{}",e);
            return DataResponse.BuildFailResponse("查询出错请重试!");
        }
    }


    /**
     *
     * 功能描述:通过id查询(缓存击穿)
     *
     * @param:
     * @return:
     * @auther: csh
     * @date: 2020/8/31 17:29
     */
    @RequestMapping("findById3/{id}")
    public DataResponse<User> findById3(@PathVariable("id")Integer id){
        if(null==id){
            return DataResponse.BuildFailResponse("参数不能为空!");
        }
        try {
            return userService.findById2(id);
        }catch (Exception e){
            log.error("findById->查询失败{}",e);
            return DataResponse.BuildFailResponse("查询出错请重试!");
        }
    }
    /**
     *
     * 功能描述:通过id查询 (缓存雪崩)
     *
     * @param:
     * @return:
     * @auther: csh
     * @date: 2020/9/3 11:40
     */
    @RequestMapping("findById4/{id}")
    public DataResponse<User> findById4(@PathVariable("id")Integer id){
        if(null==id){
            return DataResponse.BuildFailResponse("参数不能为空!");
        }
        try {
            //定义一个拥有20个并发的线程池对象
            ExecutorService service = newFixedThreadPool(20);
            Runnable runnable = new Runnable() {
                @SneakyThrows
                @Override
                public void run() {
                    userService.findById3(id);
                }
            };
            for (int i = 0; i < 1000; i++) {
                //提交线程，并并发执行
                service.submit(runnable);
            }
            return userService.findById3(id);
        }catch (Exception e){
            log.error("findById4->查询失败{}",e);
            return DataResponse.BuildFailResponse("查询出错请重试!");
        }
    }

    /**
     *
     * 功能描述:手动操作
     *
     * @param:
     * @return:
     * @auther: csh
     * @date: 2020/8/31 19:26
     */
    @RequestMapping("handlerById/{id}")
    public DataResponse<User> handlerById(@PathVariable("id")Integer id){
        if(null==id){
            return DataResponse.BuildFailResponse("参数不能为空!");
        }
        try {
            return userService.handlerById(id);
        }catch (Exception e){
            log.error("findById->查询失败{}",e);
            return DataResponse.BuildFailResponse("查询出错请重试!");
        }
    }
    /**
     *
     * 功能描述:通过sentinel测试
     *
     * @param:
     * @return:
     * @auther: csh
     * @date: 2020/9/4 16:01
     */
    @RequestMapping("findById5/{id}")
    public DataResponse<User> findById5(@PathVariable("id")Integer id){
        if(null==id){
            return DataResponse.BuildFailResponse("参数不能为空!");
        }
        try {
            return userService.handlerById(id);
        }catch (Exception e){
            log.error("findById->查询失败{}",e);
            return DataResponse.BuildFailResponse("查询出错请重试!");
        }
    }
}
